package com.ssy.lingxi.pay.utils;

import com.thoughtworks.xstream.XStream;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.text.Document;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.Socket;
import java.net.URL;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

/**
 * @version 2.0.0
 * @author:linzy
 * @date: 2021/12/27
 */
public class RefundUtils {
    private static final Logger logger = LoggerFactory.getLogger(RefundUtils.class);

    private static String sendSocketRequest(String ipAddress, int nPort, String sRequest) throws IOException {
        Socket socket = null;
        socket = new Socket(ipAddress, nPort);
        BufferedReader ins = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GB18030"));
        PrintWriter outs = new PrintWriter(socket.getOutputStream());
        outs.print(sRequest);
        outs.flush();
        socket.shutdownOutput();
        String sLine = null;
        StringBuffer sb = new StringBuffer();
        while ((sLine = ins.readLine()) != null) {
            sb.append(sLine);
        }

        ins.close();
        outs.close();
        socket.close();
        return sb.toString();
    }

    /**
     * HTTP协议对接
     * @param ipAddress
     * @param nPort
     * @param sRequest
     * @date: 2021/12/27
     * @return
     */
    private static String sendHttpRequest(String ipAddress, int nPort, String sRequest) {
        String sResult = "";
        OutputStream out = null;
        BufferedReader in = null;

        try{
            String encoding = "GB18030";
            String param = "requestXml=" + URLEncoder.encode(sRequest,encoding);
            String path = "http://" + ipAddress + ":" +nPort;
            URL url = new URL(path);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setConnectTimeout(10 * 1000);//设置连接超时时间
            conn.setDoOutput(true);//指示应用程序要将数据写入URL连接
            conn.setDoInput(true);//指示应用程序要从url连接读取数据
            //设置http请求报文头
            conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            conn.setRequestProperty("Content-Length",String.valueOf(param.length()));
            conn.setRequestProperty("Content","close");
            //发送请求报文数据
            out = conn.getOutputStream();
            out.write(param.getBytes(encoding));
            out.flush();
            out.close();
            //读取返回数据
            if(conn.getResponseCode() == 200){
                in = new BufferedReader(new InputStreamReader(conn.getInputStream(),encoding));
            }else{
                in = new BufferedReader(new InputStreamReader(conn.getErrorStream(),encoding));
            }

            String sLine;
            StringBuilder sb = new StringBuilder();
            while ((sLine = in.readLine()) != null){
                sb.append(sLine);
            }
            sResult = sb.toString();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                if(in != null){
                    in.close();
                }
                if(out != null){
                    out.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return sResult;
    }

        /**
         * @return
         * @date: 2021/12/27
         * @params userId 操作员号
         * @params password 操作员支付密码
         * @params money 退款金额
         * @params orderId 订单号
         * @description:退款接口
         */
    public static String payByCcbRefund(String ipAddress, int nPort, String requestSn,String userId, String password, String money, String orderId,String custId,String refundCode)  {
        if(StringUtils.isEmpty(requestSn)){
            //生成序列码
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            requestSn = sdf.format(new Date());
        }
        //参数对象
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?>");
        sb.append("<TX>");
        sb.append("<REQUEST_SN>" + requestSn + "</REQUEST_SN>");//请求序列码
        sb.append("<CUST_ID>" + custId +"</CUST_ID>");//商户号
        sb.append("<USER_ID>" + userId + "</USER_ID>");//操作员号
        sb.append("<PASSWORD>" + password + "</PASSWORD>");//操作员支付密码
        sb.append("<TX_CODE>5W1004</TX_CODE>");//交易请求码
        sb.append("<LANGUAGE>CN</LANGUAGE>");//语言
        sb.append("<TX_INFO>");
        sb.append("<MONEY>" + money + "</MONEY>");//退款金额
        sb.append("<ORDER>" + orderId + "</ORDER>");//退款订单号
        sb.append("<REFUND_CODE>" + refundCode + "</REFUND_CODE>");//退款流水号
        sb.append("</TX_INFO>");
        sb.append("</TX>");
        String sRequest = sb.toString();
        logger.info("退款请求报文:"+sRequest);
        String result;
        result = sendHttpRequest(ipAddress, nPort, sRequest);
        logger.info("退款响应报文:"+result);
        return result;
    }


    /**
     * @return
     * @date: 2021/12/27
     * @description:退款查询接口
     */
    public static String payByCcbRefundQuery(String ipAddress, int nPort, String requestSn,String custId,String userId, String password, String orderId,String kind)  {
        if(StringUtils.isEmpty(requestSn)){
            //生成序列码
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            requestSn = sdf.format(new Date());
        }

        //参数对象
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?>");
        sb.append("<TX>");
        sb.append("<REQUEST_SN>" + requestSn + "</REQUEST_SN>");//请求序列码
        sb.append("<CUST_ID>" + custId + "</CUST_ID>");//商户号
        sb.append("<USER_ID>" + userId + "</USER_ID>");//操作员号
        sb.append("<PASSWORD>" + password + "</PASSWORD>");//操作员支付密码
        sb.append("<TX_CODE>5W1003</TX_CODE>");//交易请求码
        sb.append("<LANGUAGE>CN</LANGUAGE>");//语言
        sb.append("<TX_INFO>");
        sb.append("<KIND>" + kind + "</KIND>");//0:未结流水,1:已结流水
        sb.append("<ORDER>" + orderId + "</ORDER>");//退款订单号
        sb.append("<NORDERBY>2</NORDERBY>");//排序 1:交易日期,2:订单号
        sb.append("<PAGE>1</PAGE>");//当前页次
        sb.append("<STATUS>3</STATUS>");//流水状态 0:交易失败,1:交易成功,2:待银行确认(针对未结流水查询);3:全部
        sb.append("</TX_INFO>");
        sb.append("</TX>");
        String sRequest = sb.toString();
        logger.info("退款流水查询请求报文:"+sRequest);
        String result = null;
        result = sendHttpRequest(ipAddress, nPort, sRequest);
        logger.info("退款查询响应报文:"+result);
        return result;
    }

    /**
     * @return
     * @date: 2021/12/27
     * @description: 支付流水查询
     */
    public static String payByCcbQuery(String ipAddress, int nPort, String userId, String password, String orderId,String kind)  {
        //生成序列码
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String REQUEST_SN = sdf.format(new Date());
        //参数对象
        StringBuffer sb = new StringBuffer();
        sb.append("<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?>");
        sb.append("<TX>");
        sb.append("<REQUEST_SN>" + REQUEST_SN + "</REQUEST_SN>");//请求序列码
        sb.append("<CUST_ID>商户号</CUST_ID>");//商户号
        sb.append("<USER_ID>" + userId + "</USER_ID>");//操作员号
        sb.append("<PASSWORD>" + password + "</PASSWORD>");//操作员支付密码
        sb.append("<TX_CODE>5W1002</TX_CODE>");//交易请求码
        sb.append("<LANGUAGE>CN</LANGUAGE>");//语言
        sb.append("<TX_INFO>");
        sb.append("<KIND>" + kind + "</KIND>");//0:未结流水,1:已结流水
        sb.append("<ORDER>" + orderId + "</ORDER>");//退款订单号
        sb.append("<DEXCEL>1</DEXCEL>");//DEXCEL
        sb.append("<NORDERBY>2</NORDERBY>");//排序 1:交易日期,2:订单号
        sb.append("<PAGE>1</PAGE>");//当前页次
        sb.append("<STATUS>3</STATUS>");//流水状态 0:交易失败,1:交易成功,2:待银行确认(针对未结流水查询);3:全部
        sb.append("</TX_INFO>");
        sb.append("</TX>");
        String sRequest = sb.toString();
        logger.info("支付流水查询请求报文:"+sRequest);
        String result = null;
        try {
            result = sendSocketRequest(ipAddress, nPort, sRequest);
        } catch (IOException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
        System.out.println(result);
        return result;
    }

    /**
     * 从 string 格式的xml 里面提出取出 Document 实体类
     * @param ret string 格式的xml
     * @return
     */
    private Object getDocumentByXMLStr(String ret) {
        XStream xStream = new XStream();
        xStream.alias("DOCUMENT", Document.class);
        xStream.processAnnotations(Document.class);
        XStream.setupDefaultSecurity(xStream);
        xStream.allowTypesByWildcard(
                new String[]{"com.xxxxx.**"}
        );
        return xStream.fromXML(ret);
    }

    //生成16位唯一的数字单号
    public static String getRequestSn(){
        //随机生成一位整数
        int random = (int) (Math.random()*9+1);
        String valueOf = String.valueOf(random);
        //生成uuid的hashCode值
        int hashCode = UUID.randomUUID().toString().hashCode();
        //可能为负数
        if(hashCode<0){
            hashCode = -hashCode;
        }
        return valueOf + String.format("%015d", hashCode);
    }
}
